/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.util.text;

/** 字符串工具类 */
public class StringFormatter {

  /**
   * 格式化字符串
   *
   * <p>此方法只是简单将占位符 {} 按照顺序替换为参数 如果想输出 {} 使用 \ 转义 { 即可，如果想输出 {} 之前的 \ 使用双转义符 \\ 即可
   *
   * <p>示例：
   *
   * <pre>
   * format("this is {} for {}", "a", "b")       -> this is a for b
   * format("this is \\{} for {}", "a", "b")     -> this is \{} for a
   * format("this is \\\\{} for {}", "a", "b")   -> this is \a for b
   * </pre>
   *
   * @param template 带占位符的字符串
   * @param args 替换参数
   * @return 格式化后的字符串
   */
  public static String format(String template, Object... args) {
    if (template == null || template.isEmpty() || args == null || args.length == 0) {
      return template;
    }

    StringBuilder sb = new StringBuilder();
    int argIndex = 0;
    int length = template.length();

    for (int i = 0; i < length; i++) {
      char c = template.charAt(i);

      if (c == '\\' && i + 1 < length) {
        char next = template.charAt(i + 1);
        if (next == '{' || next == '\\') {
          sb.append(next);
          i++; // 跳过下一个字符
        } else {
          sb.append(c);
        }
      } else if (c == '{' && i + 1 < length && template.charAt(i + 1) == '}') {
        if (argIndex < args.length) {
          sb.append(args[argIndex++]);
        } else {
          sb.append("{}"); // 参数不足时保留原占位符
        }
        i++; // 跳过 '}'
      } else {
        sb.append(c);
      }
    }

    return sb.toString();
  }
}
